package net.oschina.git.views;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.message.BasicNameValuePair;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import net.oschina.git.Activator;
import net.oschina.git.handlers.WindowsHandler;
import net.oschina.git.utils.HttpUtil;
import net.oschina.git.utils.JsonUtil;
import net.oschina.git.utils.RemoteApi;
import net.oschina.git.utils.UserData;
import net.oschina.git.utils.i18n;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;

public class Config extends Dialog {
	private Text email;
	private Text Password;
	private Text text;
	private Combo btnCloneType;
	private Composite mainComposite;
	private boolean saved;
	private Button help;

	/**
	 * Create the dialog.
	 * 
	 * @param parentShell
	 */
	public Config(Shell parentShell) {
		super(parentShell);
		WindowsHandler.config = this;
	}

	@Override
	protected void setShellStyle(int newShellStyle) {           
		super.setShellStyle(SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE | SWT.RESIZE);
	    setBlockOnOpen(false);
	}
	
	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText(i18n.login);
		shell.setImage(AbstractUIPlugin.imageDescriptorFromPlugin(Activator.getDefault().getBundle().getSymbolicName(),
				"$nl$/icons/oschina.ico").createImage());
	}

	/**
	 * Create contents of the dialog.
	 * 
	 * @param parent
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		mainComposite = parent;
		String password = UserData.getValue("password");
		String username = UserData.getValue("username");
		parent.setLayout(new GridLayout(1, false));
		Composite container = (Composite)super.createDialogArea(parent);
		container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		GridLayout gl_container = new GridLayout(3, false);
		gl_container.verticalSpacing = 10;
		container.setLayout(gl_container);

		
		Label host = new Label(container, SWT.NONE);
		host.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		host.setText(i18n.Host + ":");

		text = new Text(container, SWT.BORDER);
		GridData gd_text = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
		gd_text.widthHint = 337;
		text.setLayoutData(gd_text);
		text.setText(RemoteApi.defaultHost);
		text.setEditable(false);

		Label lblAuthType = new Label(container, SWT.NONE);
		lblAuthType.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		lblAuthType.setText(i18n.Auth_type + ":");

		btnCloneType = new Combo(container, SWT.READ_ONLY);
		btnCloneType.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

		String[] items = new String[] { "Password", "SSH" };
		btnCloneType.setItems(items);
		String cloneType = UserData.getValue("cloneType");
		if (cloneType != null && cloneType.equals("ssh")) {
			btnCloneType.select(1);
		} else {
			btnCloneType.select(0);
		}

		final Button btnSavePassword = new Button(container, SWT.CHECK);
		btnSavePassword.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		btnSavePassword.setText(i18n.Save_password);
		if (password != null && !password.isEmpty()) {
			btnSavePassword.setSelection(true);
			saved = true;
		} else {
			saved = false;
		}
		btnSavePassword.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				// TODO Auto-generated method stub
				if (btnSavePassword.getSelection()) {
					saved = true;
				} else {
					saved = false;
					UserData.removeKeyValue("passsword");
					UserData.removeKeyValue("private_token");
				}
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// TODO Auto-generated method stub

			}

		});
		CLabel lblUsername = new CLabel(container, SWT.NONE);
		lblUsername.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		lblUsername.setText(i18n.Email + "：");

		email = new Text(container, SWT.BORDER);
		GridData gd_email = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
		gd_email.widthHint = 230;
		email.setLayoutData(gd_email);

		CLabel lblPassword = new CLabel(container, SWT.NONE);
		lblPassword.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		lblPassword.setText(i18n.Password + "：");

		Password = new Text(container, SWT.BORDER | SWT.PASSWORD);
		GridData gd_Password = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
		gd_Password.widthHint = 330;
		Password.setLayoutData(gd_Password);
		Label lblDoNotHave = new Label(container, SWT.NONE);
		lblDoNotHave.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
		lblDoNotHave.setText("Do not have an account at git.oschina.net?");

		Link link = new Link(container, SWT.NONE);
		link.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		link.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				try {
					PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser()
							.openURL(new URL(RemoteApi.SignUrl));
				} catch (PartInitException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (MalformedURLException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		link.setText("<a>Sign up</a>");
		if (username != null && !username.isEmpty()&&!username.equals("N/A")) {
			email.setText(username);
		}
		if (password != null && !password.isEmpty()&&!password.equals("N/A")) {
			Password.setText(password);
		}
		return container;
	}

	/**
	 * Create contents of the button bar.
	 * 
	 * @param parent
	 */
	@Override
	protected void createButtonsForButtonBar(final Composite parent) {
		Button cancel = createButton(parent, IDialogConstants.CANCEL_ID, i18n.Cancel, false);
		help = createButton(parent, IDialogConstants.NO_ID, i18n.Help, true);
		help.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				try {
					PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser()
							.openURL(new URL(RemoteApi.helpUrl));
				} catch (PartInitException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (MalformedURLException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		Button login = createButton(parent, IDialogConstants.NO_ID, i18n.Login, true);
		login.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				String username = email.getText();
				String password = Password.getText();
				String savedPrivate_token = UserData.getValue("private_token");
				if (username.isEmpty() || password.isEmpty()) {
					MessageDialog.openError(mainComposite.getShell(), i18n.Unauthorized, i18n.loginError);
					return;
				}
				String private_token = null;
				try {
					List<NameValuePair> list = new ArrayList<NameValuePair>();
					list.add(new BasicNameValuePair("email", username));
					list.add(new BasicNameValuePair("password", password));
					String loginRep = HttpUtil.post(RemoteApi.login, list, parent.getShell());
					if (!loginRep.contains("private_token")) {
						MessageDialog.openError(mainComposite.getShell(), "Error", i18n.passwordWrong);
						return;
					}
					String responseHtml = null;
					if (savedPrivate_token == null || savedPrivate_token.equals("N/A")) {
						responseHtml = HttpUtil.post(RemoteApi.login, list, parent.getShell());
						if (responseHtml != null) {
							private_token = JsonUtil.getJsonValueFromStr(responseHtml, "private_token");
						}
					} else {
						String response = HttpUtil.get(RemoteApi.getProjects + "?private_token=" + savedPrivate_token);
						if (response.contains("message")) {
							String message = JsonUtil.getJsonValueFromStr(response, "message");
							if (message.equals("401 Unauthorized")) {
								responseHtml = HttpUtil.post(RemoteApi.login, list, parent.getShell());
								if (responseHtml != null) {
									private_token = JsonUtil.getJsonValueFromStr(responseHtml, "private_token");
								}
							}
						} else {
							private_token = savedPrivate_token;
						}
					}
					if (private_token != null && !private_token.isEmpty()) {
						CloneRepository cr = null;
						if (saved) {
							UserData.saveKeyValue("password", password);
							UserData.saveKeyValue("username", username);
							UserData.saveKeyValue("private_token", private_token);
						}
						if (btnCloneType.getSelectionIndex() == 1) {
							UserData.saveKeyValue("cloneType", "ssh");
							cr = new CloneRepository(WindowsHandler.config.getShell().getParent().getShell(),
									private_token);
						} else if (btnCloneType.getSelectionIndex() == 0) {
							if (username.isEmpty() || password.isEmpty()) {
								MessageDialog.openError(mainComposite.getShell(), "Error", i18n.loginError);
								return;
							}
							UserData.saveKeyValue("cloneType", "http");
							cr = new CloneRepository(WindowsHandler.config.getShell().getParent().getShell(),
									private_token, username, password);
						}
						WindowsHandler.cloneWindow = cr;
						WindowsHandler.root = WindowsHandler.config.getShell().getParent();
						WindowsHandler.config.getShell().dispose();
						cr.open();
					}
				} catch (ConnectTimeoutException e1) {
					// TODO Auto-generated catch block
					MessageDialog.openError(mainComposite.getShell(), "Error", "Login Timeout");
				} catch (ClientProtocolException e1) {
					// TODO Auto-generated catch block
					MessageDialog.openError(mainComposite.getShell(), "Error", e1.getMessage());
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					MessageDialog.openError(mainComposite.getShell(), "Error", "Network Issues");
				}
			}
		});
	}
}
